google rpc | | google cloud function rpc wrapper | Search

This Firebase Cloud Function provides a remote procedure call (RPC) endpoint, allowing clients to execute functions defined elsewhere and receive results as JSON responses. It handles CORS requests, extracts function names from incoming data, and utilizes a custom getResult function to execute the requested logic.

Run example

npm run import -- "firebase rpc wrapper"

firebase rpc wrapper

var cors = require('cors')({origin: true});
var process = require('process');
var functions = require('firebase-functions');
var admin = require('firebase-admin');
var importer = require('../Core');
var getResult = importer.import("rpc result");

try {
    admin.initializeApp(functions.config().firebase);
} catch (e) {
    console.log(e);
}

if(typeof module.exports === 'undefined') {
    module.exports = {};
}

module.exports.rpc = functions.https.onRequest((req, res) => {
    process.env.HOME = process.env.HOMEPATH = process.env.USERPROFILE = '';
    const config = functions.config();
    const services = Object.keys(config).reduce(k => {
        Object.keys(config[k]).forEach(s => {
            process.env[k.toUpperCase() + '_' + s.toUpperCase()] = config[k][s];
        });
    });
    
    cors(req, res, () => {
        return Promise.resolve([])
            .then(() => getResult({
                command: req.body['function'] || req.query['function'],
                result: importer.interpret(req.body['function'] || req.query['function']),
                body: req.method === 'POST' ? req.body : req.query,
                circles: ['Public']
            }))
            .then(r => {
                const result = Object.getOwnPropertyNames(r).reduce((alt, key) => {
                    alt[key] = r[key] + '';
                    return alt;
                }, {});
                console.error(result);
                return res.status(200).send(r);
            })
            // TODO: object assign error?
            .catch(e => { 
                const result = Object.getOwnPropertyNames(e).reduce((alt, key) => {
                    alt[key] = e[key] + '';
                    return alt;
                }, {});
                console.error(result);
                return res.status(500).send(result);
            });
    });
})

What the code could have been:

const admin = require('firebase-admin');
const firebaseFunctions = require('firebase-functions');
const importCore = require('../Core');
const rpcResult = importCore.import('rpc result');

admin.initializeApp(firebaseFunctions.config().firebase);

const cors = () => {
    return (req, res, next) => {
        next();
    };
};

class Config {
    constructor(config) {
        this.config = config;
    }

    getServices() {
        return Object.keys(this.config).reduce((acc, key) => {
            Object.keys(this.config[key]).forEach((service) => {
                const envKey = `${key.toUpperCase()}_${service.toUpperCase()}`;
                process.env[envKey] = this.config[key][service];
            });
            return acc;
        }, {});
    }
}

class Rpc {
    constructor(config) {
        this.config = config;
        this.services = new Config(config).getServices();
    }

    handleRequest(req, res) {
        try {
            const { body } = req;
            const { command, result, body: data, circles } = this.interpretInput(body);
            return rpcResult({
                command,
                result,
                data,
                circles,
            })
               .then((result) => {
                    return res.status(200).send(result);
                })
               .catch((error) => {
                    return res.status(500).send(error);
                });
        } catch (error) {
            console.error(error);
            return res.status(500).send(error);
        }
    }

    interpretInput(input) {
        const command = input['function'] || input.query['function'];
        const result = importCore.interpret(input['function'] || input.query['function']);
        const data = input.method === 'POST'? input.body : input.query;
        const circles = ['Public'];

        return { command, result, body: data, circles };
    }
}

module.exports = (functions) => {
    const rpc = new Rpc(functions.config());
    return functions.https.onRequest(rpc.handleRequest);
};

This code sets up a Firebase Cloud Function that acts as a remote procedure call (RPC) endpoint.

Here's a breakdown:

  1. Dependencies:

  2. Firebase Initialization:

  3. Environment Setup:

  4. RPC Endpoint:

  5. CORS Handling:

  6. Request Processing:

  7. Error Handling: